<?php

namespace App\Listeners;

use Illuminate\Database\Events\QueryExecuted;
use Illuminate\Support\Facades\Log;

class Query
{
    protected $openSlowQueryLog;
    protected $openAllQueryLog;
    protected $slowTime;

    private $bindSql;

    public function __construct()
    {
        $this->openSlowQueryLog = config('sys.open_slow_query_log');
        $this->openAllQueryLog = config('sys.open_all_query_log');
        $this->slowTime = config('sys.slow_time');
    }

    public function executed(QueryExecuted $executed)
    {
        if ($this->openAllQueryLog) {
            Log::channel('all_query')->info('all_query', ['sql' => $this->getBindSql($executed), 'time' => $executed->time . 'ms']);
        }
        if ($this->openSlowQueryLog && $executed->time > $this->slowTime) {
            Log::channel('slow_query')->warning('slow_query', ['sql' => $this->getBindSql($executed), 'time' => $executed->time . 'ms']);
        }
    }

    protected function getBindSql(QueryExecuted $executed)
    {
        if (!$this->bindSql) {
            foreach ($executed->bindings as $i => $binding) {
                if ($binding instanceof \DateTime) {
                    $executed->bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
                } else {
                    if (is_string($binding)) {
                        $executed->bindings[$i] = "'$binding'";
                    }
                }
            }
            $query = str_replace(array('%', '?'), array('%%', '%s'), $executed->sql);
            $sql = vsprintf($query, $executed->bindings);
            $this->bindSql = $sql;
        }
        return $this->bindSql;
    }


}
